package bnb

import (
	"context"
	"errors"
	"math"
	"math/big"
	"raymond/global"
	"strings"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/crypto"
)

// eth_call
type CallArg struct {
	From     common.Address `json:"from"`
	To       common.Address `json:"to"`
	Gas      string         `json:"gas"`
	GasPrice string         `json:"gas_price"`
	Value    string         `json:"value"`
	Data     string         `json:"data"`
	Nonce    string         `json:"nonce"`
}

func GetBNBCoinBalance(address string) (*big.Float, error) {
	client := global.Client()
	account := common.HexToAddress(address)
	balance, err := client.BalanceAt(context.Background(), account, nil)
	if err != nil {
		return nil, err
	}

	fbalance := new(big.Float)
	fbalance.SetString(balance.String())
	ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))

	//amt := global.WEI.ToToken(balance)

	//fmt.Println(balance, ethValue, amt)

	return ethValue, nil
}

func GetBEP20Balance(contractAddress string, address string) (*big.Float, error) {
	client := global.Client()
	callName := "eth_call"
	balanceFnSignature := []byte("balanceOf(address)")
	// 0x70a08231
	methodId := crypto.Keccak256Hash(balanceFnSignature).String()[:10]

	/*
		gasPrice, err := client.SuggestGasPrice(context.Background())
		if err != nil {
			return nil, err
		}
		gasLimit := big.NewInt(1)
		gas := new(big.Int).Mul(gasPrice, gasLimit)
	*/
	gas := big.NewInt(30000)

	result := ""
	arg := &CallArg{}
	// 部分节点需要指定Gas参数
	arg.Gas = hexutil.EncodeUint64(gas.Uint64())
	arg.To = common.HexToAddress(contractAddress)
	arg.Data = methodId + strings.Repeat("0", 24) + address[2:]
	err := client.Client().Call(&result, callName, arg, "latest")
	if err != nil {
		return nil, err
	}
	if result == "" {
		return nil, errors.New("eth token balance is null")
	}

	fbalance := new(big.Float)
	fbalance.SetString(result)
	ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))

	return ethValue, nil
}
